﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Threading;
using System.Windows.Forms;
using System.Xml.Linq;
using CoreEveprod;
using ConnectionBase;

namespace EveProd
{
	public partial class EveProd : Form
	{
		// Je connecte à la base
		DataClassesEveProdDataContext dataContext = new DataClassesEveProdDataContext();
		private Thread threadCalcul;

		public EveProd()
		{
			InitializeComponent();
		}
		
		/// <summary>
		/// Au moment du chargenment de la fenêtre Principal.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void EveProd_Load(object sender, EventArgs e)
		{
			if (ProfilProvider.GetProfil().NomProfil == null || ProfilProvider.GetProfil().NomProfil == "PasProfil")
			{
				textBoxProfilCharge.Text = @"Pas de Profil chargé";
				checkBoxStationPref.Enabled = false;
			}

			openFileDialogChargerProfil.FileOk += new CancelEventHandler(openFileDialogChargerProfil_FileOk);

			// Test sur la connexion de la base.
			if(!dataContext.DatabaseExists())
			{
				// Je met tout les composants en Enabled = FALSE.
				panelAchat.Enabled = false;
				panelTechLvl.Enabled = false;
				panelCalculUnitaire.Enabled = false;
				panelVente.Enabled = false;
				checkBoxStationPref.Enabled = false;
				buttonCalculer.Enabled = false;
				menuStrip1.Enabled = false;

				// Je préviens l'utilisateur qu'il n'y a pas de connexion avec la base.
				MessageBox.Show("Aucune connexion avec la base de donnée.","Problème connexion",MessageBoxButtons.OK,MessageBoxIcon.Exclamation);

				// Je quitte la méthode.)
				return;
			}

			#region TextBoxDateBase

			DateTime dateBase = new DateTime();

			try
			{
				dateBase = (from ii in dataContext.UpdateBase
				                select ii.LastUpdate).First();
			}
			catch(Exception ex)
			{
				UpdateBase update = new UpdateBase();
				update.LastUpdate = DateTime.Now;
				dataContext.UpdateBase.InsertOnSubmit(update);
				dataContext.SubmitChanges();
			}

			textBoxDateBase.Text = dateBase.ToString("d");

			#endregion
			
			#region ComboBoxRegions

			// Je récupère tout les noms de Région.
			var regions = (from reg in dataContext.Regions
						   orderby reg.NomRegion
						   select reg.NomRegion);

			// Et les ajoutes aux 2 ComboBox.
			foreach (var region in regions)
			{
				if (region == "Unknown") continue;
				comboBoxAchatRegion.Items.Add(region);
				comboBoxVenteRegion.Items.Add(region);
			} 
			#endregion
		}

		#region Menu du Haut

		/// <summary>
		/// Permet de quitter l'application
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void quitterToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Close();
		}

		/// <summary>
		/// Ouvre la fenêtre des résultats calculés.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void afficherRésultatToolStripMenuItem_Click(object sender, EventArgs e)
		{
			this.Enabled = false;

			FormResultat resultat = new FormResultat();
			resultat.Show();
			resultat.Closed +=new EventHandler(resultat_Closed);
		}
		void resultat_Closed(object sender, EventArgs e)
		{
			this.Enabled = true;
		}

		/// <summary>
		/// Méthode qui va lancer une fenêtre pour créer un profil.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void créerToolStripMenuItem_Click(object sender, EventArgs e)
		{
			this.Enabled = false;
			FormProfil profil = new FormProfil();
			profil.Show();
			profil.Closed += new EventHandler(profil_Closed);
		}
		void profil_Closed(object sender, EventArgs e)
		{
			this.Enabled = true;

			// Je met le nom de profil dans le textBox
			textBoxProfilCharge.Text = ProfilProvider.GetProfil().NomProfil;

			// Je vérifie que l'utilisateur à remplis les stations Vente et Achat, pour activer le checkBox.
			if(ProfilProvider.GetProfil().StationAchat != "" && ProfilProvider.GetProfil().StationVente != "")
			{
				checkBoxStationPref.Enabled = true;
			}
		}

		/// <summary>
		/// Méthode qui va lancer une fenêtre pour pouvoir modifier un profil.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void modifierToolStripMenuItem_Click(object sender, EventArgs e)
		{
			this.Enabled = false;
			EditProfil editProfil = new EditProfil();
			editProfil.Show();
			editProfil.Closed += new EventHandler(editProfil_Closed);
		}
		void editProfil_Closed(object sender, EventArgs e)
		{
			this.Enabled = true;

			// Je vérifie que l'utilisateur à remplis les stations Vente et Achat, pour activer le checkBox.
			if (ProfilProvider.GetProfil().StationAchat != "" && ProfilProvider.GetProfil().StationVente != "")
			{
				checkBoxStationPref.Enabled = true;
			}
		}

		/// <summary>
		/// Ouvre un "openFileDialog" ou nous chargeons le fichier XML du profil.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void chargerToolStripMenuItem_Click(object sender, EventArgs e)
		{
			openFileDialogChargerProfil.ShowDialog();
		}
		void openFileDialogChargerProfil_FileOk(object sender, CancelEventArgs e)
		{
			ProfilProvider.ChargerProfil(XElement.Load(openFileDialogChargerProfil.OpenFile()));
			
			ProfilDll profil = ProfilProvider.GetProfil();
			textBoxProfilCharge.Text = profil.NomProfil;

			// Je vérifie que l'utilisateur à remplis les stations Vente et Achat, pour activer le checkBox.
			if (ProfilProvider.GetProfil().StationAchat != "" && ProfilProvider.GetProfil().StationVente != "")
			{
				checkBoxStationPref.Enabled = true;
			}
		}

		/// <summary>
		/// Ouvre la fenêtre pour mettre à jour les BluePrints.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void bluePrintToolStripMenuItem_Click(object sender, EventArgs e)
		{
			this.Enabled = false;
			EditBluePrint blueprint = new EditBluePrint();
			blueprint.Show();
			blueprint.Closed += new EventHandler(bluePrint_Closed);
		}
		void bluePrint_Closed(object sender, EventArgs e)
		{
			this.Enabled = true;
		}

		/// <summary>
		/// Charge la liste de prix perso de l'utilisateur.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void chargerListeToolStripMenuItem_Click(object sender, EventArgs e)
		{
			this.Enabled = false;

			openFileDialogLoadPrice.Filter = "Fichiers XML (*.xml)|*.xml";
			openFileDialogLoadPrice.ShowDialog();
		}
		private void openFileDialogLoadPrice_FileOk(object sender, CancelEventArgs e)
		{
			this.Enabled = true;
			MarketPriceProvider.ClearListPrix();
			MarketPriceProvider.ChargerPrix(XElement.Load(openFileDialogLoadPrice.OpenFile()));
		}

		/// <summary>
		/// Permet de créer une liste de prix Perso.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void listeDePrixToolStripMenuItem_Click(object sender, EventArgs e)
		{
			this.Enabled = false;
			FormPrix listPrix = new FormPrix(true);
			listPrix.Show();
			listPrix.Closed += new EventHandler(Prix_Closed);
		}
		void Prix_Closed(object sender, EventArgs e)
		{
			this.Enabled = true;
		}
		#endregion

		#region Menu Base de donnée

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void miseÀJourToolStripMenuItem_Click(object sender, EventArgs e)
		{
			// Je désactive la fenêtre principale.
			this.Enabled = false;

			// Lancement de la nouvelle fenêtre.
			FormUpdateBase formUpdateBase = new FormUpdateBase();
			formUpdateBase.Show();
			formUpdateBase.Closed += new EventHandler(formUpdateBase_Closed);
		}
		void formUpdateBase_Closed(object sender, EventArgs e)
		{
			this.Enabled = true;
		}

		#endregion

		#region Bouton Calculé - Stop
		/// <summary>
		/// Ce bouton va lancer les calculs.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void buttonCalculer_Click(object sender, EventArgs e)
		{
			if(!VerificationDonnee(true))
				return;

			Calculer calcul = new Calculer(checkBoxTech1.Checked, checkBoxTech2.Checked, checkBoxTech3.Checked,
			                               comboBoxAchatStation.Text, comboBoxVenteStation.Text);
			
			MettreFormEnCalcul();

			threadCalcul = new Thread(new ThreadStart(calcul.CalculerBenefice));
			threadCalcul.Start();
		}

		/// <summary>
		/// Bouton qui permet de stopper les calculs en cours.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void buttonStop_Click(object sender, EventArgs e)
		{
			threadCalcul.Abort();
			MessageBox.Show("Calcul Abordé", "Annulé", MessageBoxButtons.OK, MessageBoxIcon.Information);

			MettreFormEnFonction();
		}

		/// <summary>
		/// Bouton qui lance le calcul sur un Blueprint sélectionné.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void buttonCalculerUnitaire_Click(object sender, EventArgs e)
		{
			if(!VerificationDonnee(false))
				return;
			this.Enabled = false;

			Calculer calcul = new Calculer(comboBoxAchatStation.Text, comboBoxVenteStation.Text);
			calcul.CalculerBeneficeUnitaire(comboBoxCalculUnitaire.Text);

			MessageBox.Show("Calcul terminé", "Terminé", MessageBoxButtons.OK, MessageBoxIcon.Information);

			// Affichage du résultat de Calcul
			FormResultatUnitaire formResultatUnitaire = new FormResultatUnitaire(comboBoxCalculUnitaire.Text);
			formResultatUnitaire.Show();
			formResultatUnitaire.Closed += new EventHandler(FormResultatUnitaire_Closed);
		}
		void FormResultatUnitaire_Closed(object sender, EventArgs e)
		{
			this.Enabled = true;
		}

		#endregion

		#region Mise à jour ComboxBox
		/// <summary>
		/// Méthode qui met à jour le comboxAchatSystème.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void comboBoxAchatRegion_SelectedIndexChanged(object sender, EventArgs e)
		{
			string regionSelectionne = comboBoxAchatRegion.Text;

			// Je récupère l'id de la Région.
			var idRegion = (from region in dataContext.Regions
							where region.NomRegion == regionSelectionne
							select region.IdRegion).First();

			// Je récupère les systèmes correspondant à la région sélectionné.
			var system = (from syst in dataContext.Systemes
						  where syst.IdRegion == idRegion
						  orderby syst.NomSystem
						  select syst.NomSystem);

			comboBoxAchatSystem.Items.Clear();
			comboBoxAchatSystem.Text = "";

			// Je les ajoutes dans le comboxBoxSystem
			foreach (var nomSysteme in system)
			{
				comboBoxAchatSystem.Items.Add(nomSysteme);
			}
		}

		/// <summary>
		/// Méthode qui met à jour le comboxAchatStation.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void comboBoxAchatSystem_SelectedIndexChanged(object sender, EventArgs e)
		{
			// Je récupère l'ID du système choisi.
			var idSysteme = (from syst in dataContext.Systemes
							 where syst.NomSystem == comboBoxAchatSystem.Text
							 select syst.IdSystem).First();

			// Je vais chercher les Stations liés à ce système.
			var stations = (from station in dataContext.Stations
							where station.IdSystem == idSysteme
							orderby station.NomStation
							select station.NomStation);

			comboBoxAchatStation.Items.Clear();
			comboBoxAchatStation.Text = "";

			foreach (var station in stations)
			{
				comboBoxAchatStation.Items.Add(station);
			}
		}

		/// <summary>
		/// Méthode qui met à jour le comboxVenteSystems.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void comboBoxVenteRegion_SelectedIndexChanged(object sender, EventArgs e)
		{
			string regionSelectionne = comboBoxVenteRegion.Text;

			// Je récupère l'id de la Région.
			var idRegion = (from region in dataContext.Regions
							where region.NomRegion == regionSelectionne
							select region.IdRegion).First();

			// Je récupère les systèmes correspondant à la région sélectionné.
			var system = (from syst in dataContext.Systemes
						  where syst.IdRegion == idRegion
						  orderby syst.NomSystem
						  select syst.NomSystem);

			comboBoxVenteSystem.Items.Clear();
			comboBoxVenteSystem.Text = "";

			// Je les ajoutes dans le comboxBoxSystem
			foreach (var nomSysteme in system)
			{
				comboBoxVenteSystem.Items.Add(nomSysteme);
			}
		}

		/// <summary>
		/// Méthode qui met à jour le comboxVenteStation.
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void comboBoxVenteSystem_SelectedIndexChanged(object sender, EventArgs e)
		{
			// Je récupère l'ID du système choisi.
			var idSysteme = (from syst in dataContext.Systemes
							 where syst.NomSystem == comboBoxVenteSystem.Text
							 select syst.IdSystem).First();

			// Je vais chercher les Stations liés à ce système.
			var stations = (from station in dataContext.Stations
							where station.IdSystem == idSysteme
							orderby station.NomStation
							select station.NomStation);

			comboBoxVenteStation.Items.Clear();
			comboBoxVenteStation.Text = "";

			foreach (var station in stations)
			{
				comboBoxVenteStation.Items.Add(station);
			}
		} 
		#endregion

		#region Mise à jour des CheckBox

		/// <summary>
		/// Met à jour les CheckBox
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void checkBoxTech3_CheckStateChanged(object sender, EventArgs e)
		{
			if (checkBoxTech3.Checked)
			{
				checkBoxTech2.CheckState = CheckState.Checked;
				checkBoxTech2.Enabled = false;
			}
			else
			{
				checkBoxTech2.CheckState = CheckState.Unchecked;
				checkBoxTech2.Enabled = true;
			}
		}

		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void CalculerUnBlueprint(object sender, EventArgs e)
		{
			if(checkBoxUnitaire.Checked)
			{
				// Je ferme l'accès a tout ce qui pourrait lancer un autre calcul.
				checkBoxTech1.Enabled = false;
				checkBoxTech2.Enabled = false;
				checkBoxTech3.Enabled = false;
				buttonCalculer.Enabled = false;
				comboBoxCalculUnitaire.Enabled = true;
				buttonCalculerUnitaire.Enabled = true;
				buttonCalculerUnitaire.Visible = true;

				var listBlueprint = (from bp in dataContext.ItemsEve
				                     where bp.NomItem.Contains("Blueprint")
				                     select bp.NomItem);
				comboBoxCalculUnitaire.DataSource = listBlueprint;
			}
			else
			{
				// Si j'ouvre tout les droits.
				checkBoxTech1.Enabled = true;
				checkBoxTech2.Enabled = true;
				checkBoxTech3.Enabled = true;
				comboBoxCalculUnitaire.Enabled = false;
				buttonCalculerUnitaire.Enabled = false;
				buttonCalculerUnitaire.Visible = false;
				buttonCalculer.Enabled = true;
			}
		}

		#endregion

		#region Méthodes Communes
		/// <summary>
		/// Pour remettre la fenêtre avec tout les composants en Enabled = True.
		/// </summary>
		public void MettreFormEnFonction()
		{
			this.ClientSize = new Size(653, 434);

			buttonCalculer.Enabled = true;
			menuStrip1.Enabled = true;
			if (!checkBoxUnitaire.Checked)
			{
				checkBoxTech1.Enabled = true;
				checkBoxTech2.Enabled = true;
				checkBoxTech3.Enabled = true;
			}
			checkBoxUnitaire.Enabled = true;
			comboBoxAchatStation.Enabled = true;
			comboBoxAchatSystem.Enabled = true;
			comboBoxAchatRegion.Enabled = true;
			comboBoxVenteRegion.Enabled = true;
			comboBoxVenteSystem.Enabled = true;
			comboBoxVenteStation.Enabled = true;
		}

		/// <summary>
		/// Va mettre la Form au format de calcul, resize, tout à Enabled = false
		/// </summary>
		private void MettreFormEnCalcul()
		{
			this.ClientSize = new Size(653, 498);
			buttonCalculer.Enabled = false;
			menuStrip1.Enabled = false;
			checkBoxTech1.Enabled = false;
			checkBoxTech2.Enabled = false;
			checkBoxTech3.Enabled = false;
			checkBoxUnitaire.Enabled = false;
			comboBoxAchatStation.Enabled = false;
			comboBoxAchatSystem.Enabled = false;
			comboBoxAchatRegion.Enabled = false;
			comboBoxVenteRegion.Enabled = false;
			comboBoxVenteSystem.Enabled = false;
			comboBoxVenteStation.Enabled = false;
			comboBoxCalculUnitaire.Enabled = false;
		}

		/// <summary>
		/// Vérifie les données pour un lancement de calcul.
		/// </summary>
		/// <returns></returns>
		private bool VerificationDonnee(bool quoiCheck)
		{
			// Vérification d'un Profil chargé.
			if (ProfilProvider.GetProfil().NomProfil == "PasProfil")
			{
				MessageBox.Show(@"Pas de profil sélectionné.", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return false;
			}

			if (quoiCheck)
			{
				// Vérification qu'au moins checkBox est sélectionné.
				if (!checkBoxTech1.Checked && !checkBoxTech2.Checked && !checkBoxTech3.Checked)
				{
					MessageBox.Show(@"Aucun Check Box n'est sélectionné.", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
					return false;
				}
			}

			// Vérification d'une station d'achat
			if (comboBoxAchatStation.Text == "")
			{
				MessageBox.Show(@"Aucune Station d'Achat sélectionné.", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return false;
			}

			// Vérification d'une station de vente
			if (comboBoxVenteStation.Text == "")
			{
				MessageBox.Show(@"Aucune Station de Vente sélectionné.", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
				return false;
			}

			return true;
		} 
		#endregion

		#region Méthodes appeler par Delegate
		/// <summary>
		/// Prépare la progressBar en fonction du nombre de Blueprint à Calculer.
		/// </summary>
		/// <param name="nbreBlueprint"></param>
		public void PreparationProgressBar(int nbreBlueprint)
		{
			progressBarCalculer.Minimum = 1;
			progressBarCalculer.Maximum = nbreBlueprint;
			progressBarCalculer.Value = 1;
			progressBarCalculer.Step = 1;

			labelCalculerNbre.Text = nbreBlueprint.ToString();
		}

		/// <summary>
		/// Permet de faire avancer la progressBarCalcul
		/// </summary>
		/// <param name="b">Ne sert absolument à rien.</param>
		public void AvancerProgressBar(int b)
		{
			progressBarCalculer.PerformStep();
		} 
		#endregion

		
		/// <summary>
		/// 
		/// </summary>
		/// <param name="sender"></param>
		/// <param name="e"></param>
		private void UtiliserStationsPerso_CheckChanged(object sender, EventArgs e)
		{
			// Si le checkBox est activé, il faut utilisé les stations que l'utilisateur à mis dans son profils.
			if(checkBoxStationPref.Checked)
			{
				// J'enlève d'abord ce qui est affiché.
				comboBoxVenteStation.ResetText();
				comboBoxVenteSystem.ResetText();
				comboBoxVenteRegion.ResetText();

				comboBoxAchatStation.ResetText();
				comboBoxAchatSystem.ResetText();
				comboBoxAchatRegion.ResetText();

				// Je dois vérrouiller les 2 Panels Vente et Achat.
				panelVente.Enabled = false;
				panelAchat.Enabled = false;

				/* Je dois quand même afficher les stations dans les panels. */
				
				// Je convertit les ID (string) en INT.
				var idAchat = Convert.ToInt32(ProfilProvider.GetProfil().StationAchat);
				var idVente = Convert.ToInt32(ProfilProvider.GetProfil().StationVente);

				// Je vais chercher les noms de Region, System et Station pour Vente et Achat
				var vente = (from gg in dataContext.Stations
				             where gg.IdStation == idVente
				             select new
				                    	{
				                    		stationVente = gg.NomStation,
				                    		systemVente = gg.Systemes.NomSystem,
				                    		regionVente = gg.Regions.NomRegion
				                    	}).First();

				// Et les affectent dans les comboBox.
				comboBoxVenteStation.SelectedText = vente.stationVente;
				comboBoxVenteSystem.SelectedText = vente.systemVente;
				comboBoxVenteRegion.SelectedText = vente.regionVente;

				var achat = (from gg in dataContext.Stations
							 where gg.IdStation == idAchat
							 select new
							 {
								 stationAchat = gg.NomStation,
								 systemAchat = gg.Systemes.NomSystem,
								 regionAchat = gg.Regions.NomRegion
							 }).First();

				comboBoxAchatStation.SelectedText = achat.stationAchat;
				comboBoxAchatSystem.SelectedText = achat.systemAchat;
				comboBoxAchatRegion.SelectedText = achat.regionAchat;
			}
			else
			{
				// Je réactive les panels.
				panelVente.Enabled = true;
				panelAchat.Enabled = true;
			}

		}
		
	}
}
